﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DataSystem;
using Utility.PoolSystem;

using TileGroupRef = Utility.PoolSystem.UPRef<TerrainSystem.TileGroup>;
using TileRef = Utility.PoolSystem.UPRef<TerrainSystem.Tile>;
using Utility.Math;

namespace TerrainSystem
{
	public class Tile : MonoBehaviour,IPoolCallback
	{
		#region static
		public static void SetSetting (Tile obj, TileSettingObject setting)
		{
			obj.settingObject = setting;
		}

		public static TileRef Spawn (TileSetting setting)
		{
			var tileRef = PoolManager.Spawn (setting.Prefab).GetComponent<Tile> ();
			var tile = tileRef.Component;
			tile.UPRef = tileRef;
			return tileRef;
		}

		public static void SetTileGroup (TileRef tileRef, TileGroupRef tileGroupRef, Vector2Int localCoord)
		{
			var tile = tileRef.Component;
			if (tile != null)
			{
				tile.TileGroupRef = tileGroupRef;
				tile.LocalCoord = localCoord;
				tile.transform.SetParent (tileGroupRef.Component?.Transform_Tiles);
				tile.transform.localPosition = new Vector3 (localCoord.x, 0, localCoord.y);
				tile.transform.localRotation = default;
			}
		}
		#endregion

		private int ID_Color = Shader.PropertyToID ("_Color");

		private Color normal_Color => Setting?.Color ?? Color.white;

		private MaterialPropertyBlock block;
		private Renderer Renderer { get; set; }

		private void SetColor ()
		{
			if (Renderer == null) Renderer = GetComponentInChildren<Renderer> ();
			if (block == null) block = new MaterialPropertyBlock ();
			if (Renderer)
			{
				Renderer.GetPropertyBlock (block);
				block.SetColor (ID_Color, normal_Color);
				Renderer.SetPropertyBlock (block);
			}
		}
		
		[SerializeField] TileSettingObject settingObject;
		public TileSetting Setting => settingObject.GetSetting ();
		public TileSetting.TerrainLayers TerrainLayer => Setting.TerrainLayer;
		public float SurfaceHeight => Setting.SurfaceHeight;

		public Rotation4 Orientation => (TileGroupRef.Component?.Orientation ?? Rotation4.Forward) + LocalOrientation;
		public Rotation4 LocalOrientation => Rotation4.Forward;

		public bool CanBuild => Setting.CanBuild;
		public bool IsGround => TerrainLayer == TileSetting.TerrainLayers.Ground;
		public bool IsPlatform => TerrainLayer == TileSetting.TerrainLayers.Platform;

		public TileRef UPRef { get; private set; }
		public TileGroupRef TileGroupRef { get; private set; }

		public Vector2Int LocalCoord { get; private set; }
		public Vector2Int Coord => TileGroupRef.Component?.LocalToWorldCoord (LocalCoord) ?? LocalCoord;


		public void OnSpawn ()
		{
			SetColor ();
		}

		public void OnDespawn ()
		{
			
		}
	}
}